package com.ls.server.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ls.server.domain.McpService;
import com.ls.server.dto.McpQueryDTO;
import com.ls.server.dto.McpServiceDTO;
import com.ls.server.mapper.McpServiceMapper;
import com.ls.server.service.McpServiceService;
import com.ls.server.vo.McpServiceVO;
import com.ls.server.vo.PageResult;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * MCP服务Service实现类
 */
@Service
public class McpServiceServiceImpl implements McpServiceService {

    private final McpServiceMapper mcpServiceMapper;

    public McpServiceServiceImpl(McpServiceMapper mcpServiceMapper) {
        this.mcpServiceMapper = mcpServiceMapper;
    }

    @Override
    public PageResult<McpServiceVO> page(McpQueryDTO queryDTO) {
        LambdaQueryWrapper<McpService> wrapper = Wrappers.lambdaQuery();

        // 关键词搜索
        if (StringUtils.hasText(queryDTO.getKeyword())) {
            wrapper.like(McpService::getName, queryDTO.getKeyword())
                   .or()
                   .like(McpService::getDescription, queryDTO.getKeyword());
        }

        // 标签筛选
        if (StringUtils.hasText(queryDTO.getTag())) {
            wrapper.like(McpService::getTags, queryDTO.getTag());
        }

        // MCP类型筛选
        if (StringUtils.hasText(queryDTO.getMcpType())) {
            wrapper.like(McpService::getMcpType, queryDTO.getMcpType());
        }

        // 按排序号和创建时间排序
        wrapper.orderByAsc(McpService::getOrderNum)
               .orderByDesc(McpService::getCreateTime);

        // 分页查询
        Page<McpService> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
        Page<McpService> resultPage = mcpServiceMapper.selectPage(page, wrapper);

        // 转换结果
        List<McpServiceVO> list = resultPage.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());

        // 返回分页结果，传入当前页码和每页条数
        return new PageResult<>(list, resultPage.getTotal(), queryDTO.getPageNum(), queryDTO.getPageSize());
    }

    @Override
    public List<McpServiceVO> listEnabledServices() {
        LambdaQueryWrapper<McpService> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(McpService::getEnabled, true)
               .orderByAsc(McpService::getOrderNum)
               .orderByDesc(McpService::getCreateTime);

        return mcpServiceMapper.selectList(wrapper).stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public McpServiceVO getServiceById(Long id) {
        McpService mcpService = mcpServiceMapper.selectById(id);
        return mcpService != null ? convertToVO(mcpService) : null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean createService(McpServiceDTO dto) {
        McpService mcpService = new McpService();
        BeanUtils.copyProperties(dto, mcpService);

        // 设置默认值
        if (mcpService.getEnabled() == null) {
            mcpService.setEnabled(true);
        }
        if (mcpService.getOrderNum() == null) {
            mcpService.setOrderNum(0);
        }

        LocalDateTime now = LocalDateTime.now();
        mcpService.setCreateTime(now);
        mcpService.setUpdateTime(now);

        // 验证并保存
        validateMcpService(mcpService);
        return mcpServiceMapper.insert(mcpService) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateService(McpServiceDTO dto) {
        McpService mcpService = mcpServiceMapper.selectById(dto.getId());
        if (mcpService == null) {
            return false;
        }

        BeanUtils.copyProperties(dto, mcpService);
        mcpService.setUpdateTime(LocalDateTime.now());

        // 验证并更新
        validateMcpService(mcpService);
        return mcpServiceMapper.updateById(mcpService) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteService(Long id) {
        return mcpServiceMapper.deleteById(id) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateStatus(Long id, Boolean enabled) {
        McpService mcpService = mcpServiceMapper.selectById(id);
        if (mcpService == null) {
            return false;
        }

        mcpService.setEnabled(enabled);
        mcpService.setUpdateTime(LocalDateTime.now());

        return mcpServiceMapper.updateById(mcpService) > 0;
    }

    @Override
    public List<McpService> getServiceById(String idString) {
        // 如果idString为空，则返回空
        if (!StringUtils.hasText(idString)) {
            return new ArrayList<>();
        }
        // 将idString转换为Long列表
        List<Long> ids = Arrays.stream(idString.split(","))
                .map(Long::parseLong)
                .collect(Collectors.toList());
        return mcpServiceMapper.selectByIds(ids);
    }

    /**
     * 验证MCP服务信息
     * @param mcpService MCP服务
     */
    private void validateMcpService(McpService mcpService) {
        // 验证MCP类型和相关配置
        String mcpType = mcpService.getMcpType();
        if (StringUtils.hasText(mcpType)) {
            // 包含SSE类型，需要URL
            if (mcpType.contains("SSE") && !StringUtils.hasText(mcpService.getUrl())) {
                throw new IllegalArgumentException("选择SSE类型时，URL必填");
            }

            // 包含Stdio类型，需要服务配置
            if (mcpType.contains("Stdio") && !StringUtils.hasText(mcpService.getServiceConfig())) {
                throw new IllegalArgumentException("选择Stdio类型时，MCP服务配置必填");
            }

            // 全选类型，URL和服务配置都必填
            if (mcpType.contains("SSE") && mcpType.contains("Stdio")) {
                if (!StringUtils.hasText(mcpService.getUrl()) || !StringUtils.hasText(mcpService.getServiceConfig())) {
                    throw new IllegalArgumentException("同时选择SSE和Stdio类型时，URL和MCP服务配置都必填");
                }
            }
        }
    }

    /**
     * 将实体转换为VO
     * @param mcpService MCP服务实体
     * @return MCP服务VO
     */
    private McpServiceVO convertToVO(McpService mcpService) {
        McpServiceVO vo = new McpServiceVO();
        BeanUtils.copyProperties(mcpService, vo);
        return vo;
    }
}
